package org.mysfit.ctp4j.core.service.impl;

import java.math.BigDecimal;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.mysfit.ctp4j.core.service.FkDataService;
import org.mysfit.ctp4j.core.service.MarketService;
import org.mysfit.ctp4j.core.service.SkDataService;
import org.mysfit.ctp4j.core.service.TradeService;
import org.mysfit.ctp4j.infra.entity.SkData;
import org.mysfit.ctp4j.infra.mapper.SkDataMapper;
import org.mysfit.ctp4j.infra.utils.TradeDataUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ctp.thosttraderapi.CThostFtdcDepthMarketDataField;

/**
 * <p>
 * sk 服务实现类
 * </p>
 *
 * @author long.gf
 * @since 2022-12-02
 */
@Service
public class MarketServiceImpl implements MarketService {
	
	@Autowired
	private SkDataMapper skMapper;

	@Autowired
	private FkDataService fkService;
	
	@Autowired
	private SkDataService skService;
	
	@Autowired
	private TradeService tradeService;
	
	private static 	ThreadPoolExecutor exe;
	
	static {
		exe=new ThreadPoolExecutor(10, 10,
                10L, TimeUnit.MINUTES,
                new LinkedBlockingQueue<Runnable>());
		exe.allowCoreThreadTimeOut(true);
		Runtime.getRuntime().addShutdownHook(new Thread(()-> {
			exe.shutdown();
		}));
	}
	
	
	@Override
	public void saveData(CThostFtdcDepthMarketDataField data)  {
		if (data != null) {
			SkData sk = new SkData();
			String fid = data.getInstrumentID();
			String day = data.getTradingDay().substring(0,4)+"-"+data.getTradingDay().substring(4,6)+"-"+data.getTradingDay().substring(6);
			String time = data.getUpdateTime();
			sk.setFtime(day + " " + time);
			int millisec = data.getUpdateMillisec();
			if(millisec == 0) {
				if(!TradeDataUtils.getInstance(fkService, skService,tradeService).checkUk(fid, day, time)) {
					return ;
				}
				String volKey = "vol" + "_"+fid ;
				String amtKey = "amt" + "_"+fid ;
				BigDecimal lastVol = null == TradeDataUtils.LAST_MK_MAP.get(volKey) ? BigDecimal.ZERO : TradeDataUtils.LAST_MK_MAP.get(volKey);
				BigDecimal lastAmount = null == TradeDataUtils.LAST_MK_MAP.get(amtKey) ? BigDecimal.ZERO : TradeDataUtils.LAST_MK_MAP.get(amtKey);
				sk.setFid(fid);
				sk.setFp(new BigDecimal(data.getLastPrice()));
				sk.setFv(new BigDecimal(data.getVolume()).subtract(lastVol));
				sk.setFa(new BigDecimal(data.getTurnover()).subtract(lastAmount));
				sk.setTotalFv(new BigDecimal(data.getVolume()));
				sk.setTotalFa(new BigDecimal(data.getTurnover()));
				skMapper.insert(sk);
				TradeDataUtils.LAST_MK_MAP.put(volKey, new BigDecimal(data.getVolume()));
				TradeDataUtils.LAST_MK_MAP.put(amtKey, new BigDecimal(data.getTurnover()));
				TradeDataUtils.getInstance(fkService, skService,tradeService).insertFk(sk);
				TradeDataUtils.getInstance(fkService, skService,tradeService).refershSk(sk);
				TradeDataUtils.getInstance(fkService, skService,tradeService).refershFk(sk);
				exe.execute(new Runnable() {
					@Override
					public void run() {
						 tradeService.doPolyOrder(sk);
					}
				});
			}
         } 
	}
	
}
